package util;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.resource.ClassPathResource;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpHost;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestClientBuilder;
import org.elasticsearch.client.RestHighLevelClient;
import org.joda.time.DateTime;
import org.slf4j.Logger;

import java.io.BufferedWriter;
import java.io.FileReader;
import java.sql.Connection;
import java.sql.DriverManager;
import java.util.Properties;
import java.util.Scanner;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * 公共方法类
 */
public class CommonUtil {
    /**
     * 初始化数据库
     */
    public static Connection initDataBase(Logger log, Scanner scanner, AtomicInteger fetchSize) throws Exception {
        String driver;
        String url;
        String username;
        String password;
        String fetchSizeStr;
        log.info("******配置数据库参数*******");
        log.info("是否使用配置文件配置？ 1（是） ， 0（否）");

        String tmp = CommonUtil.receiveLine(log, scanner);
        assertNull(tmp);
        switch (tmp) {
            case "1":
                log.info("请输入配置文件（包含路径且后缀为properties，properties样式看样例）");
                log.info("如若使用包内文件，前面加classpath:");
                tmp = CommonUtil.receiveLine(log, scanner);
                assertNull(tmp);
                if (!tmp.endsWith("properties")) {
                    throw new Exception("配置文件后缀不正确！！");
                }
                Properties properties = new Properties();
                final String dbProperties = tmp;
                if (dbProperties.startsWith("classpath")) {
                    String[] split = dbProperties.split(":");
                    ClassPathResource classPathResource = new ClassPathResource(split[1]);
                    properties.load(classPathResource.getStream());
                } else {
                    properties.load(new FileReader(tmp));
                }
                driver = properties.getProperty("jdbc.driver");
                url = properties.getProperty("jdbc.url");
                username = properties.getProperty("jdbc.username");
                password = properties.getProperty("jdbc.password");
                fetchSizeStr = properties.getProperty("jdbc.fetchSize");
                break;
            case "0":
                log.info("请输入jdbc.driver:）");
                tmp = CommonUtil.receiveLine(log, scanner);
                assertNull(tmp);
                driver = tmp;

                log.info("请输入jdbc.url:）");
                tmp = CommonUtil.receiveLine(log, scanner);
                assertNull(tmp);
                url = tmp;

                log.info("请输入jdbc.username:）");
                tmp = CommonUtil.receiveLine(log, scanner);
                assertNull(tmp);
                username = tmp;

                log.info("请输入jdbc.password:）");
                tmp = CommonUtil.receiveLine(log, scanner);
                assertNull(tmp);
                password = tmp;

                log.info("请输入jdbc.fetchSize:）");
                tmp = CommonUtil.receiveLine(log, scanner);
                assertNull(tmp);
                fetchSizeStr = tmp;
                break;
            default:
                throw new Exception("输入有误。。。");
        }
        log.info("driver:" + driver);
        log.info("url:" + url);
        log.info("username:" + username);
        log.info("password:" + password);
        log.info("fetchSize:" + fetchSize);
        if (fetchSizeStr != null && !fetchSizeStr.trim().equals("")) {
            fetchSize.set(Integer.parseInt(fetchSizeStr));
        }
        return initConnection(driver, url, username, password);
    }

    /**
     * 初始化数据库连接
     */
    private static Connection initConnection(String driver, String url, String username, String password) throws Exception {
        Connection connection = null;
        Class.forName(driver);
        connection = DriverManager.getConnection(url, username, password);
        connection.setAutoCommit(false);
        return connection;
    }

    /**
     * 记录日志
     */
    public static void log(BufferedWriter writer, String log) throws Exception {
        log = new DateTime().toString("yyyy-MM-dd HH:mm:ss").toString() + "  " + log;
        System.out.println(log);
        writer.newLine();
        writer.write(log);
        writer.flush();
    }


    /**
     * 校验输入空值
     */
    public static void assertNull(String tmp) throws Exception {
        if (tmp == null || tmp.trim().equals("")) {
            throw new Exception("输入值不允许为空！！");
        }
    }


    /**
     * 初始化elasticSearch
     */
    public static RestHighLevelClient initElasticSearchClient(Logger log, Scanner scanner) throws Exception {
        String ip = null;
        String port = null;
        String needPassword = null;
        String username = null;
        String password = null;

        log.info("******配置elasticSearch参数*******");
        log.info("是否使用配置文件配置？ 1（是） ， 0（否）");

        String tmp = CommonUtil.receiveLine(log, scanner);
        assertNull(tmp);
        switch (tmp) {
            case "1":
                log.info("请输入配置文件（包含路径且后缀为properties，properties样式看样例）");
                log.info("如若使用包内文件，前面加classpath:");
                tmp = CommonUtil.receiveLine(log, scanner);
                assertNull(tmp);
                if (!tmp.endsWith("properties")) {
                    throw new Exception("配置文件后缀不正确！！");
                }
                Properties properties = new Properties();
                final String dbProperties = tmp;
                if (dbProperties.startsWith("classpath")) {
                    String[] split = dbProperties.split(":");
                    ClassPathResource classPathResource = new ClassPathResource(split[1]);
                    properties.load(classPathResource.getStream());
                } else {
                    properties.load(new FileReader(tmp));
                }
                ip = properties.getProperty("elasticSearch.ip");
                port = properties.getProperty("elasticSearch.port");
                needPassword = properties.getProperty("elasticSearch.needPassword");
                username = properties.getProperty("elasticSearch.username");
                password = properties.getProperty("elasticSearch.password");
                break;
            case "0":
                log.info("请输入elasticSearch.ip:）");
                tmp = CommonUtil.receiveLine(log, scanner);
                assertNull(tmp);
                ip = tmp;

                log.info("请输入elasticSearch.port:）");
                tmp = CommonUtil.receiveLine(log, scanner);
                assertNull(tmp);
                port = tmp;

                log.info("请输入elasticSearch.scheme(0:no password | 1:need password):）");
                tmp = CommonUtil.receiveLine(log, scanner);
                assertNull(tmp);
                needPassword = tmp;
                if (StringUtils.equals(needPassword, "1")) {
                    log.info("请输入elasticSearch.username:）");
                    tmp = CommonUtil.receiveLine(log, scanner);
                    assertNull(tmp);
                    username = tmp;

                    log.info("请输入elasticSearch.password:）");
                    tmp = CommonUtil.receiveLine(log, scanner);
                    assertNull(tmp);
                    password = tmp;
                }
                break;
            default:
                throw new Exception("输入有误。。。");
        }
        log.info("ip:" + ip);
        log.info("port:" + port);
        log.info("scheme:" + needPassword);
        if (StringUtils.equals(needPassword, "1")) {
            log.info("username:" + username);
            log.info("password:" + password);
        }
        RestHighLevelClient client = null;
        if (StringUtils.equals(needPassword, "1")) {
            HttpHost host = new HttpHost(ip, Integer.parseInt(port), HttpHost.DEFAULT_SCHEME_NAME);
            RestClientBuilder builder = RestClient.builder(host);
            CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
            credentialsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(username, password));
            builder.setHttpClientConfigCallback(f -> f.setDefaultCredentialsProvider(credentialsProvider));
            client = new RestHighLevelClient(builder);
        } else {
            HttpHost host = new HttpHost(ip, Integer.parseInt(port), HttpHost.DEFAULT_SCHEME_NAME);
            client = new RestHighLevelClient(RestClient.builder(host));
        }
        return client;
    }

    /**
     * 接收输入值
     *
     * @param log     日志类
     * @param scanner 输入接收类
     * @return 返回输入内容
     */
    public static String receiveLine(Logger log, Scanner scanner) throws Exception {
        final String nextLine = scanner.nextLine();
        log.info("输入为：{}", nextLine);
        return nextLine;
    }

}
